package com.xoa.controller.workflow;

import com.xoa.dao.WFE.WFEFormTypeMapper;
import com.xoa.dao.users.UsersMapper;
import com.xoa.dao.work.WorkMapper;
import com.xoa.dao.workflow.FlowRunPrcsMapper;
import com.xoa.model.enclosure.Attachment;
import com.xoa.model.users.Users;
import com.xoa.model.workflow.*;
import com.xoa.service.WFE.WFERunner.WFEFlowRun;
import com.xoa.service.workflow.flowtype.FlowRunService;
import com.xoa.util.*;
import com.xoa.util.common.StringUtils;
import com.xoa.util.common.session.SessionUtils;
import com.xoa.util.common.wrapper.BaseWrappers;
import com.xoa.util.page.PageParams;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.DataFormatException;

/**
 * Created by gsb on 2017/8/14.
 */
@RestController
@RequestMapping("/flowRun")
public class FlowRunController {

    @Autowired
    private FlowRunService flowRunService;

    @Autowired
    private WFEFlowRun wfeFlowRun;

    @Autowired
    private WorkMapper workMapper;

    @Autowired
    private WFEFormTypeMapper wfeFormTypeMapper;

    @Autowired
    private FlowRunPrcsMapper flowRunPrcsMapper;

    @Autowired
    private UsersMapper usersMapper;

    /**
     * @param state     查询范围：1.我发起的。2.我经办的。5.指定发起人。6.指定办理人。7.我查阅的
     * @param runId
     * @param flowId
     * @param runName
     * @param beginDate
     * @param endDate
     * @param workLevel 优先级：0 普通  2 紧急
     * @param status    状态值：1.正在执行。4.已经结束
     * @param userId
     * @param request
     * @param page
     * @param pageSize
     * @param useFlag
     * @param output    导出
     * @param response
     * @return
     */
    @RequestMapping("/queryFlowRun")
    public BaseWrappers queryFlowRunList(Integer state, Integer runId, Integer flowId, String runName, String beginDate, String endDate, String workLevel, String status, String userId, HttpServletRequest request,String wdfqWork,
                                         @RequestParam(name = "page", required = false, defaultValue = "1") Integer page,
                                         @RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize,
                                         @RequestParam(name = "useFlag", required = false, defaultValue = "true") Boolean useFlag,
                                         @RequestParam(name = "output", required = false, defaultValue = "0") String output, HttpServletResponse response) {
        Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
        Users users = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
        return wfeFlowRun.queryFlowRun(state, runId, flowId, runName, beginDate, endDate, workLevel, status, userId, page, pageSize, useFlag, users, output, response, request,"");
    }

    //统计工作查询条数
    @RequestMapping("/queryFlowRunCount")
    public BaseWrappers queryFlowRunCount(HttpServletRequest request) {
        return flowRunService.queryFlowRunCount(request);
    }

    //保存高级查询导出表单数据
    @RequestMapping("/saveFlowData")
    @ResponseBody
    public AjaxJson saveFlowData(Integer flowId, @RequestParam(name = "formdata", required = false) String formdata, HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        AjaxJson ajaxJson = new AjaxJson();
        Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
        Users users = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
        String sqlType = "xoa" + (String) request.getSession().getAttribute(
                "loginDateSouse");
        //判读当前系统
        //读取配置文件
        try {
            ResourceBundle rb = ResourceBundle.getBundle("upload");
            String osName = System.getProperty("os.name");
            StringBuffer path = new StringBuffer();
            StringBuffer buffer = new StringBuffer();
            if (osName.toLowerCase().startsWith("win")) {
                //sb=sb.append(rb.getString("upload.win"));
                //判断路径是否是相对路径，如果是的话，加上运行的路径
                String uploadPath = rb.getString("upload.win");
                if (uploadPath.indexOf(":") == -1) {
                    //获取运行时的路径
                    String basePath = this.getClass().getClassLoader().getResource(".").getPath() + File.pathSeparator;
                    //获取截取后的路径
                    String str2 = "";
                    if (basePath.indexOf("/xoa") != -1) {
                        //获取字符串的长度
                        int length = basePath.length();
                        //返回指定字符在此字符串中第一次出现处的索引
                        int index = basePath.indexOf("/xoa");
                        //从指定位置开始到指定位置结束截取字符串
                        str2 = basePath.substring(0, index);
                    }
                    path = path.append(str2 + "/xoa");
                }
                path.append(uploadPath);
                buffer = buffer.append(rb.getString("upload.win"));
            } else {
                path = path.append(rb.getString("upload.linux"));
                buffer = buffer.append(rb.getString("upload.linux"));
            }
            String fileName = "flow_data" + flowId + ".txt";
            File dest = new File(path.toString(), fileName);
            PrintStream ps = new PrintStream(new FileOutputStream(dest));
            ps.println(formdata);

            Map<String, Object> param = new HashMap<String, Object>();
            param.put("tableName", "flow_data_" + flowId);
            if (StringUtils.checkNull(sqlType)) {
                param.put("tableSchema", "xoa1001");
            } else {
                param.put("tableSchema", sqlType);
            }
            List<String> columns = workMapper.showColumns(param);
            //没有表则返回提示信息
            Map<String, Object> map = new HashMap<String, Object>();
            if (columns.size() == 0) {
                map.put("state", 0);
                map.put("message", Constant.noData);
            } else {
                map.put("state", 1);
            }
            ajaxJson.setAttributes(map);
            ajaxJson.setFlag(true);
            ajaxJson.setMsg("OK");
        } catch (Exception e) {
            ajaxJson.setFlag(false);
            ajaxJson.setMsg(e.getMessage());
        }
        return ajaxJson;
    }

    //高级查询导出
    @RequestMapping("/exportFlowData")
    public void exportFlowData(Integer flowId, HttpServletRequest request,
                                /*  @RequestParam(name = "page", required = false, defaultValue = "1") Integer page,
                                  @RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize,
                                  @RequestParam(name = "useFlag", required = false, defaultValue = "true")  Boolean useFlag,*/
                               HttpServletResponse response) throws IOException {
        Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
        Users users = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
        //读取配置文件
        ResourceBundle rb = ResourceBundle.getBundle("upload");
        String osName = System.getProperty("os.name");
        StringBuffer path = new StringBuffer();
        StringBuffer buffer = new StringBuffer();
        if (osName.toLowerCase().startsWith("win")) {
            //sb=sb.append(rb.getString("upload.win"));
            //判断路径是否是相对路径，如果是的话，加上运行的路径
            String uploadPath = rb.getString("upload.win");
            if (uploadPath.indexOf(":") == -1) {
                //获取运行时的路径
                String basePath = this.getClass().getClassLoader().getResource(".").getPath() + File.pathSeparator;
                //获取截取后的路径
                String str2 = "";
                if (basePath.indexOf("/xoa") != -1) {
                    //获取字符串的长度
                    int length = basePath.length();
                    //返回指定字符在此字符串中第一次出现处的索引
                    int index = basePath.indexOf("/xoa");
                    //从指定位置开始到指定位置结束截取字符串
                    str2 = basePath.substring(0, index);
                }
                path = path.append(str2 + "/xoa");
            }
            path.append(uploadPath);
            buffer = buffer.append(rb.getString("upload.win"));
        } else {
            path = path.append(rb.getString("upload.linux"));
            buffer = buffer.append(rb.getString("upload.linux"));
        }
        String fileName = "flow_data" + flowId + ".txt";
        File dest = new File(path.toString() + System.getProperty("file.separator") + fileName);
        BufferedReader bf = new BufferedReader(new FileReader(dest));
        String content = "";
        StringBuilder sb = new StringBuilder();
        while (content != null) {
            content = bf.readLine();
            if (content == null) {
                break;
            }
            sb.append(content.trim());
        }
        bf.close();
        String formdata = sb.toString();
        dest.delete();
        wfeFlowRun.exportFlowData(flowId, formdata, users, response);
    }

    /**
     * 查询流程步骤日志
     * 王禹萌
     * 2018-07-19 15：23
     *
     * @param page
     * @param pageSize
     * @param useFlag
     * @param starTime         开始时间
     * @param endTime          结束时间
     * @param runId            流水号
     * @param flowName         流程名
     * @param jobsName         工作名称
     * @param operatingType    操作类型 “0”所有操作
     * @param ProcessingPerson 操作人
     * @param ip               地址
     * @return
     */

    @RequestMapping(value = "/selFlowRunLog", produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public ToJson<FlowRunLog> selFlowRunLog(@RequestParam(name = "page", required = false, defaultValue = "1") Integer page,
                                            @RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize,
                                            @RequestParam(name = "useFlag", required = false, defaultValue = "true") Boolean useFlag,
                                            @RequestParam(name = "starTime", required = false) String starTime,
                                            @RequestParam(name = "endTime", required = false) String endTime,
                                            @RequestParam(name = "runId", required = false) String runId,
                                            @RequestParam(name = "flowName", required = false) String flowName,
                                            @RequestParam(name = "jobsName", required = false) String jobsName,//工作名称
                                            @RequestParam(name = "type", required = false) String operatingType,//操作类型
                                            @RequestParam(name = "ProcessingPerson", required = false) String ProcessingPerson,//操作人
                                            @RequestParam(name = "ip", required = false) String ip) {
        return flowRunService.selFlowRunLog(page, pageSize, useFlag, starTime, endTime, runId, flowName, jobsName, operatingType, ProcessingPerson, ip);
    }

    /**
     * 流程步骤日志删除
     * 王禹萌
     * 2018-07-06
     *
     * @param logId 根据日志Id删除
     * @return
     */
    @RequestMapping(value = "/delFlowRunLog", produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public ToJson<FlowRunLog> delFlowRunLog(Integer logId) {
        return flowRunService.delFlowRunLog(logId);
    }


    /**
     * 高级查询
     *
     * @return
     * @author zlf
     */
    @RequestMapping(value = "/toSeniorQuery")
    @ResponseBody
    public AjaxJson toSeniorQuery(HttpServletRequest request, HttpServletResponse response, Integer page, Integer pageSize, boolean useFlag) {
        AjaxJson ajaxJson = new AjaxJson();
        int kongjiancishu = 0;
        //获取cookie中当前用户
        Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
        Users users = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
        String sqlType = "xoa" + (String) request.getSession().getAttribute(
                "loginDateSouse");
        //接受前台传入的参数
        Map map = request.getParameterMap();
        //用于存储传入参数
        Map map1 = new HashMap();
        //分页插件
        PageParams pageParams = new PageParams();
        pageParams.setUseFlag(useFlag);
        pageParams.setPage(page);
        pageParams.setPageSize(pageSize);

        map1.put("page", pageParams);
        //定义拼接的sql
        StringBuffer conditionSql = new StringBuffer();
        //前台传入查询参数组装
        for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
            Map.Entry element = (Map.Entry) iter.next();
            Object strKey = element.getKey();
            String[] value = (String[]) element.getValue();
            String key = strKey.toString();

            String val = value[0];
            //判断是否有表单数据条件
            if (key.contains("relation_")) {
                String num = key.replace("relation_", "");
                String operator = "";
                String name = ((String[]) map.get("DATA_" + num))[0];
                if ("".equals(name)) {
                    continue;
                }
                if (name.equals("SELECT_ALL_VALUE")) {
                    continue;
                }

                switch (Integer.parseInt(val)) {
                    case 0:
                        operator = "0";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", operator);
                        }
                        break;
                    case 1:
                        operator = "=";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", operator);
                            conditionSql.append("and frd.DATA_" + num + " = '" + name + "' ");
                        }
                        break;
                    case 2:
                        operator = ">";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", operator);
                            conditionSql.append("and frd.DATA_" + num + " &gt; " + name + " ");
                        }
                        break;
                    case 3:
                        operator = "<";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", operator);
                            conditionSql.append("and frd.DATA_" + num + " &lt; " + name + " ");
                        }
                        break;
                    case 4:
                        operator = ">=";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", operator);
                            conditionSql.append("and frd.DATA_" + num + " &gt;= " + name + " ");
                        }
                        break;
                    case 5:
                        operator = "<=";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", operator);
                            conditionSql.append("and frd.DATA_" + num + " &lt;= " + name + " ");
                        }
                        break;
                    case 6:
                        operator = "<>";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", operator);
                            conditionSql.append("and frd.DATA_" + num + " != " + name + " ");
                        }
                        break;
                    case 7:
                        operator = "开始为";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", "like1");
                            conditionSql.append("and frd.DATA_" + num + " like '" + name + "%' ");
                        }
                        break;
                    case 8:
                        operator = "包含";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", "like2");
                            conditionSql.append("and frd.DATA_" + num + " like '%" + name + "%' ");
                        }
                        break;
                    case 9:
                        operator = "结束为";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, name);
                            map1.put("DATA_" + num + "_OPER", "like3");
                            conditionSql.append("and frd.DATA_" + num + " like '%" + name + "' ");
                        }
                        break;
                    case 10:
                        operator = "is null";
                        if (!StringUtils.checkNull(name)) {
                            map1.put("DATA_" + num, "");
                            map1.put("DATA_" + num + "_OPER", operator);
                            conditionSql.append("and frd.DATA_" + num + " is null ");
                        }
                        break;
                }
            }
            //flowStatus 流程状态0所有，1，已结束，2执行中
            if (key.equals("flowStatus")) {
                if (!StringUtils.checkNull(val)) {
                    map1.put("status", Integer.parseInt(val));
                }
            }
            //flowQueryType查询范围：0全部 1我发起的 2我经办的 3我管理的，
            if (key.equals("flowQueryType")) {
                map1.put("flowQueryType", Integer.parseInt(val));
            }
            //流程发起人
            if (key.equals("beginUserId")) {
                if (!StringUtils.checkNull(val)) {
                    map1.put("beginUser", val);
                    map1.put("userId", val);
                }
            }
            //名称/文号条件判断
            if (key.equals("runNameRelation")) {
                String operator = "";
                String rName = ((String[]) map.get("runName"))[0];
                if (!StringUtils.checkNull(rName)) {
                    switch (Integer.parseInt(val)) {
                        case 1:
                            operator = "=";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 1);
                            break;
                        case 2:
                            operator = ">";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 2);
                            break;
                        case 3:
                            operator = "<";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 3);
                            break;
                        case 4:
                            operator = ">=";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 4);
                            break;
                        case 5:
                            operator = "<=";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 5);
                            break;
                        case 6:
                            operator = "<>";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 6);
                            break;
                        case 7:
                            operator = "开始为";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 7);
                            // map1.put("runName", " like '"+rName + "%' ");
                            break;
                        case 8:
                            operator = "包含";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 8);
                            // map1.put("runName", " like '%"+rName + "%' ");
                            break;
                        case 9:
                            operator = "结束为";
                            map1.put("runName", rName);
                            map1.put("runNameOper", 9);
                            // map1.put("runName", " like '%"+rName + "' ");
                            break;
                        case 10:
                            operator = "is null";
                            map1.put("runName", rName);
                            map1.put("runNameOper", operator);
                            break;
                    }
                }
            }
            if (key.equals("beginDate")) {
                if (!StringUtils.checkNull(val)) {
                    map1.put("start1", val + " 00:00:00");
                }
            }
            if (key.equals("endDate")) {
                if (!StringUtils.checkNull(val)) {
                    map1.put("start2", val + " 23:59:59");
                }
            }
            if (key.equals("endDate1")) {
                if (!StringUtils.checkNull(val)) {
                    map1.put("endTime1", val + " 00:00:00");
                }
            }
            if (key.equals("endDate2")) {
                if (!StringUtils.checkNull(val)) {
                    map1.put("endTime2", val + " 23:59:59");
                }
            }
            if (key.equals("attachmentName")) {
                map1.put("attachmentName", val);
                map1.put("attachmentNameOper", "like2");
            }
            if (key.equals("flowId")) {
                map1.put("flowId", Integer.parseInt(val));
                map1.put("flowDataFlowId", "flow_data_" + val);
            }
            if (key.equals("condFormula")) {
                map1.put("condFormula", val);
            }
            //显示字段
            if (key.equals("showFields")) {
                map1.put("showFields", val);
            }
            //分组字段
            if (key.equals("sort")) {
                map1.put("sortYuan", val);
                if (!StringUtils.checkNull(val)) {
                    if (checkParm(val)){
                        if (val.equals("fr.END_FLAG")) {
                            val = val.replace("fr.END_FLAG", "CASE fr.END_TIME \n" +
                                    "WHEN '2000-01-01 00:00:00' THEN\n" +
                                    "'进行中' ELSE '已结束' \n" +
                                    "END as END_FLAG ");
                            map1.put("sort", val);
                            map1.put("sort1", "fr.RUN_ID");
                        } else {
                            map1.put("sort", val);
                            map1.put("sort1", val);
                        }
                    }else{
                        map1.put("sort", "fr.RUN_ID");
                        map1.put("sort1", "fr.RUN_ID");
                    }


                }
            }
            //排序
            if (key.equals("order")) {
                if (!StringUtils.checkNull(val)) {
                    if (val.equals("ASC")||val.equals("DESC")){
                        map1.put("order", val);
                    }else{
                        map1.put("order", "DESC");
                    }
                }
            }

            //类型
            if (key.equals("type")) {
                if (!StringUtils.checkNull(val)) {
                    map1.put("type", val);
                }
            }
        }
        try {
            //统计显示字段
            String showFields = map1.get("showFields").toString();
            String[] fileds = showFields.split(",");
            //默认排序字段
            String sortFields = map1.get("sortYuan").toString();
            StringBuffer sb = new StringBuffer();
            if (!StringUtils.checkNull(showFields)) {
                if (!showFields.equals(sortFields)) {
                    sb.append(sortFields).append(",");
                    List<String> list1 = new ArrayList<String>();
                    list1.add(map1.get("sortYuan").toString());
                    for (int i = 0; i < fileds.length; i++) {
                        if (!list1.contains(fileds[i])) {
                            if (i < fileds.length - 1) {
                                sb.append(fileds[i]).append(",");
                            } else {
                                sb.append(fileds[i]);
                            }
                        }
                    }
                    showFields = sb.toString();
                    fileds = showFields.split(",");
                }
            } else {
                showFields = sortFields;
            }
            fileds = showFields.split(",");
            if (showFields.contains("END_FLAG")) {
                showFields = showFields.replace("fr.END_FLAG", "CASE \n" +
                        "WHEN fr.END_TIME IS NULL THEN\n" +
                        "'进行中' ELSE '已结束' \n" +
                        "END as END_FLAG ");
            }

            map1.put("showFields", showFields);

            //表单数据条件
            if (!StringUtils.checkNull(conditionSql.toString())) {
                map1.put("conditionSql", conditionSql.toString());
            }
            String type = map1.get("type").toString();
            //  if ("0".equals(type)) {
            //我经办的
            if ("2".equals(map1.get("flowQueryType").toString()) || "1".equals((map1.get("flowQueryType").toString()))) {
                map1.put("userId", users.getUserId());
                map1.put("flowId", map1.get("flowId"));
//                    Map m = new HashMap();
//                    m.put("userId", users.getUserId());
//                    m.put("flowId", map1.get("flowId"));
//                    List<Integer> runIds = wfeFlowRun.queryRunIdByFlowId(m);
//                    map1.put("runIds", runIds);
            }
            List<FlowRunModelPrcs> flowRuns = wfeFlowRun.toSeniorQuery(map1);
            //开始时间带 .0 消掉
            for (int i = 0; i < flowRuns.size(); i++) {
                String beginName = flowRuns.get(i).getBeginTime().substring(0, flowRuns.get(i).getBeginTime().length() - 2);
                flowRuns.get(i).setBeginTime(beginName);
//                  String endTime = flowRuns.get(i).getEndTime().substring(0,flowRuns.get(i).getEndTime().length()-2);
//                  flowRuns.get(i).setBeginTime(endTime);
            }


            for (FlowRunModelPrcs flowRunModelPrcs : flowRuns) {
                List<Attachment> list = FileUploadUtil.findAtachment(flowRunModelPrcs.getAttachmentId(), flowRunModelPrcs.getAttachmentName(), sqlType);
                flowRunModelPrcs.setList(list);
                if (!StringUtils.checkNull(flowRunModelPrcs.getEndTime())) {
                    flowRunModelPrcs.setStatus("已结束");
                } else {
                    flowRunModelPrcs.setStatus("执行中");
                }
            }
            ajaxJson.setFlag(true);
            ajaxJson.setObj(flowRuns);
            ajaxJson.setTotleNum(pageParams.getTotal());
            ajaxJson.setMsg("OK");

            //  }
            if ("1".equals(type)) {

                Integer flowId = (Integer) map1.get("flowId");
                List<FlowFormType> allFlowForm = wfeFormTypeMapper.getFrombyFlowId(flowId);
                FlowFormType flowFormType = allFlowForm.get(0);
                //列字段
                List<String> titleList = new ArrayList<>();

                //解析html
                Document document = HtmlUtil.getDom(flowFormType.getPrintModel());
                String title = null;
                List<String> listSort = new ArrayList<String>();
                for (int i = 0; i < fileds.length; i++) {

                    if (fileds[i].equals("fr.RUN_ID")) {
                        title = "流水号";
                        titleList.add(title);
                        listSort.add("RUN_ID");
                        continue;
                    }
                    if (fileds[i].equals("fr.RUN_NAME")) {
                        title = "流程名称/标题";
                        titleList.add(title);
                        listSort.add("RUN_NAME");
                        continue;
                    }
                    if (fileds[i].equals("fr.END_FLAG")) {
                        title = "流程状态";
                        titleList.add(title);
                        listSort.add("END_FLAG");
                        continue;
                    }
                    if (fileds[i].equals("fr.BEGIN_TIME")) {
                        title = "流程开始日期";
                        titleList.add(title);
                        listSort.add("BEGIN_TIME");
                        continue;
                    }
                    String str1 = fileds[i].substring(fileds[i].indexOf(".") + 1, fileds[i].length());
                    title = HtmlUtil.getDocumentDataType(document, str1);
                    //获得列表控件的子标题
                    if (title.equals("listing")) {
                        kongjiancishu = i;
                        String data = getLvfield(document, str1);
                        if (data != null && data.length() > 0) {
                            String[] dataArray = data.replaceAll("`", "` ").split("`");
                            //去除截取产生的空白字符
                            dataArray = Arrays.copyOf(dataArray, dataArray.length - 1);
                            titleList.add("操作");
                            titleList.add("序号");
                            for (String str : dataArray) {
                                titleList.add(str);
                            }
                            listSort.add(str1);
                        }
                    } else {
                        title = HtmlUtil.getDocumentTitle(document, str1);
                        titleList.add(title);
                        listSort.add(str1);
                    }
                }
                 /*   if (showFields.contains("END_FLAG")) {
                        showFields = showFields.replace("fr.END_FLAG", "CASE fr.END_TIME \n" +
                                "WHEN '2000-01-01 00:00:00' THEN\n" +
                                "'进行中' ELSE '已结束' \n" +
                                "END as END_FLAG ");
                        map1.put("showFields", showFields);
                    }*/
                //展示页面数据
                List<FlowDataResult> listAll = new ArrayList<>();
                List<List> dispList = null;
                List<String> listCol = null;
                List<List> listChild = null;
                FlowDataResult flowDataResult = null;
                //Map<String, Object> mapAll = new HashMap<String, Object>();
                //所有分组字段
                List<String> sortAll = workMapper.selectSort(map1);

                for (int i = 0; i < sortAll.size(); i++) {
                    //行显示数据
                    flowDataResult = new FlowDataResult();
                    //分组字段
                    String sort = sortAll.get(i);

                    if (map1.get("sort").toString().contains("END_FLAG")) {
                        if (sort.equals("进行中")) {
                            map1.put("sortValue", "fr.END_TIME ='2000-01-01 00:00:00' ");
                        } else {
                            map1.put("sortValue", "fr.END_TIME !='2000-01-01 00:00:00' ");
                        }
                    } else {
                        String sortValue = map1.get("sort") + " = " + "'" + sort + "'";
                        map1.put("sortValue", sortValue);
                    }

                    //每个分组对应的数据
                    List<Map<String, Object>> list = workMapper.selectAllBySort(map1);
                    //开始时间带 .0 消掉
                    Object BEGIN_TIME = list.get(0).get("BEGIN _TIME");
                    String beginName = String.valueOf(BEGIN_TIME).substring(0, String.valueOf(BEGIN_TIME).length() - 2);
                    list.get(0).put("BEGIN_TIME", beginName);
                    dispList = new ArrayList<List>();
                    for (int j = 0; j < list.size(); j++) {
                        listCol = new ArrayList<String>();
                        Map<String, Object> map2 = list.get(j);
                        for (int c = 0; c < listSort.size(); c++) {
                            listCol.add(map2.get(listSort.get(c)).toString());
                        }
                        dispList.add(listCol);
                    }
                    flowDataResult.setDispList(dispList);
                    listAll.add(flowDataResult);
                }
                List<List> all = new ArrayList<>();
                all.add(titleList);
                all.add(listAll);
                this.exportFlowReportExcel(all, response, kongjiancishu);
            }
        } catch (Exception e) {
            ajaxJson.setMsg(e.getMessage());
            ajaxJson.setFlag(false);
        }
        return ajaxJson;
    }


    //导出
    private void exportFlowReportExcel(List<List> excelList, HttpServletResponse response, int kongjiancishu) {
        List<String> titleList = excelList.get(0);
        List<FlowDataResult> bodyList = excelList.get(1);
        int col = 0;//列
        int count = 1;//行数
        int rowStatrtIndex = 0;//合并单元格起始索引
        int rowEndIndex = 0;//合并单元格终止索引
        int stratStrCell = 0;
        int endStrCell = 0;
        int strCells = 0;
        int frontOffice = 0;
        try {
            // 获取当前时间
            Calendar c = Calendar.getInstance();
            String time = "" + c.get(Calendar.YEAR) + (c.get(Calendar.MONTH) + 1)
                    + c.get(Calendar.DAY_OF_MONTH) + c.get(Calendar.HOUR_OF_DAY)
                    + c.get(Calendar.MINUTE);
            StringBuffer stringBuffer = new StringBuffer();
            HSSFWorkbook wb = new HSSFWorkbook();
            // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet sheet = wb.createSheet("工作流分组统计报表");

            // 第四步，创建单元格，并设置值表头 设置表头居中
            HSSFFont font = wb.createFont();
            font.setFontHeightInPoints((short) 12); // 字体高度
            font.setColor(HSSFFont.COLOR_NORMAL); // 字体颜色
            font.setFontName("宋体"); // 字体
            font.setBold(true); // 宽度
            font.setItalic(false); // 是否使用斜体
            HSSFCellStyle style = wb.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式
            style.setFont(font);
            HSSFRow row = sheet.createRow((int) 0);
            HSSFFont font1 = wb.createFont();
            font1.setFontHeightInPoints((short) 12); // 字体高度
            font1.setColor(HSSFFont.COLOR_NORMAL); // 字体颜色
            font1.setFontName("宋体"); // 字体
            font1.setBold(true); // 宽度
            font1.setItalic(false); // 是否使用斜体
            HSSFCellStyle style1 = wb.createCellStyle();
            style1.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式
            style1.setVerticalAlignment(VerticalAlignment.CENTER);
            style1.setFont(font1);
            int allCells = 0;
            for (int i = 0; i < titleList.size(); i++) {
                HSSFCell cell = row.createCell((short) i);
                cell.setCellValue(titleList.get(i));
                cell.setCellStyle(style);
            }

            if (bodyList != null && bodyList.size() > 0) {
                for (int i = 0; i < bodyList.size(); i++) {
                    rowStatrtIndex = count;
                    for (int j = 0; j < bodyList.get(i).getDispList().size(); j++) {
                        ArrayList list = new ArrayList();
                        //存在列表控件时
                        if (kongjiancishu != 0) {
                            if ((String.valueOf(bodyList.get(i).getDispList().get(j).get(kongjiancishu))).contains("|")) {
                                //截取出计算结果
                                String[] kongjianStr = String.valueOf(bodyList.get(i).getDispList().get(j).get(kongjiancishu)).split("\\|");
                                for (String str : kongjianStr) {
                                    kongjianStr[kongjianStr.length - 1] = kongjianStr[kongjianStr.length - 1].replaceAll("`", "` ");
                                }
                                String[] kongjianStr2 = new String[kongjianStr.length];
                                for (int x = 0; x < kongjianStr.length; x++) {
                                    if (kongjianStr[x].contains("\r\n")) {
                                        kongjianStr2 = kongjianStr[x].split("\r\n");
                                    }
                                }
                                //控件值放到集合
                                for (int zz = 0; zz < kongjianStr2.length; zz++) {
                                    String str = "`" + (zz + 1) + "`" + kongjianStr2[zz];
                                    list.add(str);
                                }
                                //存放合计值
                                kongjianStr[kongjianStr.length - 1] = "合计``" + kongjianStr[kongjianStr.length - 1];
                                list.add(kongjianStr[kongjianStr.length - 1]);
                            } else {
                                String[] kongjianStr = String.valueOf(bodyList.get(i).getDispList().get(j).get(kongjiancishu)).split("\r\n");
                                for (int zz = 0; zz < kongjianStr.length; zz++) {
                                    String str = "`" + (zz + 1) + "`" + kongjianStr[zz];
                                    list.add(str);
                                }
                                kongjianStr[kongjianStr.length - 1] = "合计" + kongjianStr[kongjianStr.length - 1];
                                list.add(kongjianStr[kongjianStr.length - 1]);
                            }
                        }

                        // frontOffice = dataList.size();
                        if (list != null && list.size() > 0) {
                            List<String> dataList = bodyList.get(i).getDispList().get(j);
                            List<String> dataList2;
                            dataList2 = dataList;
                            dataList2.add(kongjiancishu + 1, " ");
                            dataList2.add(kongjiancishu + 2, " ");
                            for (int x = 0; x < list.size(); x++) {
                                String[] str = String.valueOf(list.get(x)).replaceAll("`", "` ").split("`");
                                HSSFRow row1 = sheet.createRow(count);
                                strCells = str.length;
                                allCells = strCells + dataList.size() - 1;
                                if (str != null && str.length > 0) {
                                    for (int ii = 0; ii < str.length; ii++) {
                                        if (ii == 0) {
                                            stratStrCell = col + kongjiancishu;
                                        }
                                        //控件值填写到表格中
                                        HSSFCell cell = row1.createCell(col + kongjiancishu);
                                        cell.setCellValue(str[ii]);
                                        cell.setCellStyle(style1);
                                        col++;
                                    }
                                    endStrCell = col + kongjiancishu;
                                    col = 0;
                                    count++;
                                }
                                if (dataList != null && dataList.size() > 0) {
                                    for (int cc = 0; cc < dataList.size() - 2; cc++) {
                                        /*
                                        编写正常数据
                                        控件之前数据
                                         */
                                        if (cc < kongjiancishu) {
                                            HSSFCell dataCell = row1.createCell(col);
                                            dataCell.setCellValue(dataList.get(cc));
                                            dataCell.setCellStyle(style1);
                                            col++;
                                        } else if (cc > kongjiancishu) {
                                            //控件之后数据
                                            HSSFCell dataCell = row1.createCell(col + strCells);
                                            dataCell.setCellValue(dataList2.get(cc + 2));
                                            dataCell.setCellStyle(style1);
                                            col++;
                                        }
                                    }
                                    col = 0;
                                }
                            }
                        } else {
                            //无列表控件导出
                            List<String> rowList = new ArrayList<>();
                            count++;
                            HSSFRow r = sheet.createRow(count - 1);
                            // rowList.add(bodyList.get(i).getDisp_name());
                            if (bodyList.get(i).getDispCount() != null && bodyList.get(i).getDispCount() > 0) {
                                rowList.add(bodyList.get(i).getDispCount() + "");
                            }
                            for (int n = 0; n < bodyList.get(i).getDispList().get(j).size(); n++) {
                                rowList.add(bodyList.get(i).getDispList().get(j).get(n) + "");
                            }
                            for (int b = 0; b < rowList.size(); b++) {
                                HSSFCell cell2 = r.createCell(col);
                                cell2.setCellValue(String.valueOf(rowList.get(b)));
                                cell2.setCellStyle(style1);
                                col++;
                            }
                            col = 0;
                        }

                    }
                    //合并单元格
                    /*if (bodyList.get(i).getDispList().size() > 1) {
                        CellRangeAddress region = new CellRangeAddress((count + 1 - bodyList.get(i).getDispList().size()), count, 0, 0);
                        sheet.addMergedRegion(region);
                        if (bodyList.get(i).getDispCount() != null && bodyList.get(i).getDispCount() > 1) {
                            sheet.addMergedRegion(new CellRangeAddress((count + 1 - bodyList.get(i).getDispList().size()), count, 1, 1));
                        }
                    }*/

                    rowEndIndex = count - 1;
                    //合并行
                    for (int dd = 0; dd < stratStrCell; dd++) {
                        CellRangeAddress region = new CellRangeAddress(rowStatrtIndex, rowEndIndex, dd, dd);
                        //CellRangeAddress region3 = new CellRangeAddress(rowStatrtIndex,rowEndIndex,frontOffice,frontOffice);
                        sheet.addMergedRegion(region);
                        // sheet.addMergedRegion(region3);
                    }

                    //考虑列表控件在中间情况
                    if (allCells > endStrCell) {
                        //-2是为了空出序号跟操作
                        for (int ff = endStrCell; endStrCell < allCells - 2; endStrCell++) {
                            CellRangeAddress region2 = new CellRangeAddress(rowStatrtIndex, rowEndIndex, ff, ff);
                            ff++;
                            sheet.addMergedRegion(region2);
                        }
                    }
                }
            }
            stringBuffer.append("工作流数据报表").append(time.toString()).append(".xls");

            // 设置每一列的宽度
            sheet.setDefaultColumnWidth(15);
            String fileName = stringBuffer.toString();
            response.setHeader("Content-disposition", "attachment;filename="
                    + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/msexcel;charset=UTF-8");
            OutputStream out = response.getOutputStream();
            wb.write(out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 批量导出工作查询数据
     *
     * @param
     * @param response
     * @throws Exception
     */
    @RequestMapping("/exportFlowRunBatch")
    @ResponseBody
    public void exportFlowRunBatch(HttpServletRequest request, HttpServletResponse response) {
        String runIds = request.getParameter("runIds");
        List<String> runBatch = Arrays.asList(runIds.split(","));
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("allRunIds", runBatch);
        this.wfeFlowRun.exportFlowRunBatch(request, response, map);

    }


    public static String getLvfield(Document document, String str) {
        //默认表单上name属性无重复
        Elements elements = document.select("[name=" + str + "]");
        String title = null;
        String field = null;
        if (elements.size() > 0) {
            Pattern p = Pattern.compile("[\u4e00-\u9fa5]+");
            title = elements.get(0).attr("lv_title");
            Matcher m = p.matcher(title);
            if (m.find()) {
                return title;
            } else {
                field = elements.get(0).attr("lv_field");
                m = p.matcher(field);
                if (m.find()) {
                    return field;
                }
            }
        }
        return title;
    }
    /**
     * 查找出当前办理人的前十条数据
     */
    @RequestMapping("/findFLow")
    @ResponseBody
    public ToJson findFLow(HttpServletRequest request) {
       return this.wfeFlowRun.findFLow(request);
    }
    /**
     * 进行保存删除关联流程的runid
     */
    @RequestMapping("/saveRelationRunIds")
    @ResponseBody
    public ToJson saveRelationRunIds(HttpServletRequest request) {
        ToJson json=new ToJson();
        this.wfeFlowRun.saveRelationRunIds(request);
        json.setFlag(0);
        return json;
    }
    /**
     * 查找已关联的流程
     */
    @RequestMapping("/findrelationRunIds")
    @ResponseBody
    public ToJson findrelationRunIds(HttpServletRequest request) {
        return this.wfeFlowRun.findrelationRunIds(request);
    }
    /**
     * 查看工作详情添加验证
     */
    @RequestMapping("/checking")
    @ResponseBody
    public ToJson checking(HttpServletRequest request) {
        ToJson json=new ToJson();
        String checks = request.getParameter("checks");//前台传的编码规则
        Date date=new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy:MM:dd");
        String format = dateFormat.format(date);
        long time=0;
        try{
            Date parse = dateFormat.parse(format);
            time=parse.getTime();
        }catch (Exception e){
        }
       String newTime="a9387d5ee8435f6f969c90f637db3425"+String.valueOf(time);//获取当前的编码
        if(newTime==checks){
            json.setObject(1);
        }else{
            json.setObject(0);
        }
        json.setFlag(0);
        return json;
    }
    //根据id查询flowRun
    @RequestMapping("/queryFlowRunById")
    public BaseWrappers queryFlowRunById(HttpServletRequest request) {
        BaseWrappers<FlowRun> baseWrapper=new BaseWrappers();
        String runId = request.getParameter("runId");
        FlowRun flowRun = flowRunService.find(Integer.parseInt(runId));
        baseWrapper.setFlag(true);
        baseWrapper.setStatus(true);
        baseWrapper.setObject(flowRun);
        return baseWrapper;
    }
    //收发文当前步骤办理人状态
    @RequestMapping("/stepStatus")
    @ResponseBody
    public ToJson stepStatus(HttpServletRequest request, Integer runId, Integer step) {
        ToJson json=new ToJson();
        List<FlowRunPrcs> flowRunPrcs = flowRunPrcsMapper.stepStatus(runId, step);
        for (FlowRunPrcs flowRunPrcs1:flowRunPrcs){
            flowRunPrcs1.setUserName(usersMapper.getUsernameByUserId(flowRunPrcs1.getUserId()));
            // 步骤状态(1-未接收,2-办理中,3-转交下一步，下一步经办人无人接收,4-已办结,5-自由流程预设步骤,6-已挂起,)'
            if ("1".equals(flowRunPrcs1.getPrcsFlag())){
                flowRunPrcs1.setPrcsFlag("未接受");
            }else if("2".equals(flowRunPrcs1.getPrcsFlag())){
                flowRunPrcs1.setPrcsFlag("办理中");
            }else if("3".equals(flowRunPrcs1.getPrcsFlag())){
                flowRunPrcs1.setPrcsFlag("转交下一步，下一步经办人无人接收");
            }else if("4".equals(flowRunPrcs1.getPrcsFlag())){
                flowRunPrcs1.setPrcsFlag("已办结");
            }else if("5".equals(flowRunPrcs1.getPrcsFlag())){
                flowRunPrcs1.setPrcsFlag("自由流程预设步骤");
            }else if("6".equals(flowRunPrcs1.getPrcsFlag())){
                flowRunPrcs1.setPrcsFlag("已挂起");
            }
        }
        json.setObj(flowRunPrcs);
        json.setFlag(0);
        return json;
    }


    public boolean checkParm(String sort){
        String a[] = {"fr.RUN_ID","fr.RUN_NAME","fr.END_FLAG","fr.BEGIN_TIME"};
        if (Arrays.asList(a).contains(sort)){
            return true;
        }else{
            return checkNum(sort);
        }

    }
    public static boolean checkNum(String itemId) {
        if (!itemId.contains("frd.DATA_")){
            return false;
        }
        String number = itemId.split("frd.DATA_")[1];
        if (number != null && !"".equals(number.trim())) {
            return number.matches("^[0-9]*$");
        } else {
            return false;
        }

    }


    @RequestMapping("/savePresetUser")
    @ResponseBody
    public AjaxJson savePresetUser(HttpServletRequest request,String text,Integer runId){
        AjaxJson ajaxJson = new AjaxJson();
        try{
            int a= wfeFlowRun.updatePreSetUser(runId,text);
            if (a>0){
                ajaxJson.setFlag(true);
                ajaxJson.setMsg("OK");
            }else{
                ajaxJson.setFlag(false);
                ajaxJson.setMsg("false");
            }
        }catch (Exception e){
            ajaxJson.setFlag(false);
            ajaxJson.setMsg(e.getMessage());
        }
        return ajaxJson;
    }

}
